package alert

import (
	"crypto/md5"
	"fmt"
	"net"
)

import (
	"util"
)

const STATUS_OK = 1
const STATUS_WARNING = 2
const STATUS_ERROR = 3

const Item_Length = 445

type SMonitorUdpSenderStatusItem struct {
	SzMonitorServerIp  string  //[31]byte  //监控服务器IP
	NMonitorServerPort uint32  //监控服务器端口
	SzModuleName       string  //[128]byte //模块的全路径名称
	SzPointName        string  //[51]byte  //监控点名称
	ByteStatus         byte    //监控点状态
	NValue1            int32   //监控数值1
	NValue2            int32   //监控数值2
	FValue3            float32 //监控数值3
	SzValue            string  //[101]byte //监控数值
	SzErrorInfo        string  //[101]byte //如果出异常情况，在这里描述故障说明
	MD5                [16]byte
}

func NewItem(ip string, port uint32, moduleName, pointName string) *SMonitorUdpSenderStatusItem {
	s := new(SMonitorUdpSenderStatusItem)
	s.SzMonitorServerIp = ip
	s.NMonitorServerPort = port
	s.SzModuleName = moduleName
	s.SzPointName = pointName
	s.ByteStatus = STATUS_OK

	return s
}

func (s *SMonitorUdpSenderStatusItem) enCode() (re []byte) {
	re = make([]byte, Item_Length)
	copy(re[:31], s.SzMonitorServerIp)
	copy(re[31:35], util.Uint32ToByte(s.NMonitorServerPort))
	copy(re[35:163], s.SzModuleName)
	copy(re[163:214], s.SzPointName)
	re[214] = s.ByteStatus
	copy(re[215:219], util.Int32ToByte(s.NValue1))
	copy(re[219:223], util.Int32ToByte(s.NValue2))
	copy(re[223:227], util.Float32ToByte(s.FValue3))
	copy(re[227:328], s.SzValue)
	copy(re[328:429], s.SzErrorInfo)
	s.MD5 = md5.Sum(re[:429])
	copy(re[429:], s.MD5[0:])
	return
}

func (s *SMonitorUdpSenderStatusItem) Send() error {
	conn, err := net.Dial("udp", fmt.Sprintf("%v:%v", s.SzMonitorServerIp, s.NMonitorServerPort))
	if err != nil {
		return fmt.Errorf("net.Dial(%v:%v): %v", s.SzMonitorServerIp, s.NMonitorServerPort, err)
	}
	defer conn.Close()

	b := s.enCode()
	n := 0
	length := len(b)
	for n < length {
		m, err := conn.Write(b[n:])
		if err != nil {
			return fmt.Errorf("conn.Write(): %v", err)
		}
		n += m
	}
	return nil
}

func (s *SMonitorUdpSenderStatusItem) SetOK() {
	s.ByteStatus = STATUS_OK
}

func (s *SMonitorUdpSenderStatusItem) SetWarn() {
	s.ByteStatus = STATUS_WARNING
}

func (s *SMonitorUdpSenderStatusItem) SetErr() {
	s.ByteStatus = STATUS_ERROR
}

func (s *SMonitorUdpSenderStatusItem) SetNValue(value1, value2 int32) {
	s.NValue1 = value1
	s.NValue2 = value2
}

func (s *SMonitorUdpSenderStatusItem) SetFValue(value float32) {
	s.FValue3 = value
}

func (s *SMonitorUdpSenderStatusItem) SetSzValue(value string) {
	s.SzValue = value
}

func (s *SMonitorUdpSenderStatusItem) SetErrInfo(info string) {
	s.SzErrorInfo = info
}
